﻿using Autofac;
using BaseAuthRole.IService;
using BaseAuthRole.Repository;
using BaseAuthRole.Service;
using Coldairarrow.Util;
using FreeSql;
using Lotus.AspNetCore;
using Quartz.Impl;
using Quartz;
using RS.Environment;
using System;
using System.Collections.Specialized;
using System.Threading.Tasks;
using BaseAuthRole.Domain.Input;
using CSRedis;
using MassTransit;
using log4net;
using BaseAuthRole.DTO.User;

namespace BaseAuthRole.Schedule
{
    class Program
    {
        public static IUserService? userService = null;
        public static IBaseLotusClient? baseLotusClient = null;
        public static IFreeSql? fsql = null;


        public static CSRedisClient csredis = new CSRedis.CSRedisClient(ConfigurationHelper.GetAppSettings("RedisConfig"));
        public static int LockTimeOut = Convert.ToInt32(ConfigurationHelper.GetAppSettings("LockTimeOut"));


        static async Task Main(string[] args)
        {
            System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

            Container.Init();

            //数据库注入
            AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
            AppContext.SetSwitch("Npgsql.DisableDateTimeInfinityConversions", true);

            fsql = new FreeSqlBuilder()
            .UseConnectionString(DataType.PostgreSQL, ConfigurationHelper.GetAppSettings("PgSqlCon"))
            .UseAutoSyncStructure(true)
            .Build();

            RedisHelper.Initialization(csredis);

            var uow = new FreeSql.UnitOfWorkManager(fsql);

            //为生成雪花Id提供机器Id
            new IdHelperBootstrapper()
                .SetWorkderId(Convert.ToInt64("10"))
                .Boot();

            userService = new UserService(new AuthRepository(uow), uow, new RS.Tool.DataBase.CSRedisHelper(), new RS.Tool.SDK.FeiShu.FeiShuClient("", ""), new Lutos.Dictionary.SDK.Core.LtDictionaryClient(""));
            baseLotusClient = new BaseLotusClient(new Lotus.AspNetCore.Client.Option.BaseLutosOption
            {
                AppId = ConfigurationHelper.GetAppSettings("TDoauthClientId"),
                AppSecret = ConfigurationHelper.GetAppSettings("TDoauthClientSecret"),
                UserDomain = ConfigurationHelper.GetAppSettings("LotusUserGatewayUrl")
            });

            //1、声明一个调度工厂
            ISchedulerFactory _schedulerFactory = new StdSchedulerFactory();
            //2、通过调度工厂获得调度器
            IScheduler _scheduler = await _schedulerFactory.GetScheduler();
            //3、开启调度器
            await _scheduler.Start();
            //4、创建一个触发器
            ITrigger trigger = TriggerBuilder.Create()
                            .WithSimpleSchedule(x => x.WithIntervalInSeconds(Convert.ToInt32(ConfigurationHelper.GetAppSettings("IntervalInSecond"))).RepeatForever())
                            .Build();
            //5、创建任务
            IJobDetail jobDetail = JobBuilder.Create<UpdateUserInfoJob>()
                            .WithIdentity("job_createLogTable", "group1")
                            .Build();
            //6、将触发器和任务器绑定到调度器中
            await _scheduler.ScheduleJob(jobDetail, trigger);

            var trigger2 = TriggerBuilder.Create().WithDailyTimeIntervalSchedule(
                 w => w.OnEveryDay() //设置每天
                     .StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(10, 00)) //设置每天开始于几点
                     .EndingDailyAt(TimeOfDay.HourMinuteAndSecondOfDay(10, 10, 0)) //设置每日结束于几点
                     .WithIntervalInMinutes(20)//间隔分钟
               ).Build();
            IJobDetail jobDetail2 = JobBuilder.Create<CreatTableJob>()
                            .WithIdentity("job_creatTable", "group2")
                            .Build();
            await _scheduler.ScheduleJob(jobDetail2, trigger2);

            //7、启动
            await _scheduler.Start();

            Thread.Sleep(Timeout.Infinite);
        }
    }

    public class UpdateUserInfoJob : IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            var redisLock = RedisHelper.Instance.TryLock("Task_UserOrg", Program.LockTimeOut);
            if (redisLock == null)
            {
                Console.WriteLine($"{DateTime.UtcNow.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")}: 任务在其它服务已启动");
                return null;
            }

            Console.WriteLine($"{DateTime.UtcNow.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")}: 开始执行任务");

            int page = 1;

            while (true)
            {
                try
                {
                    var info = Program.baseLotusClient.GetLotusUserInfoList(new Lotus.Domain.Input.Lotus.GetLotusUserInfoListInput
                    {
                        PageNo = page,
                        PageSize = 100
                    });

                    if (!info.IsError)
                    {
                        if (info.Result.Data.DataList.Count > 0)
                        {
                            try
                            {
                                var temp = info.Result.Data.DataList.Where(p => p.EmployeeTypeCode != "98" && p.State != null && p.Gender != null).ToList().Select(o => new AddOrUpdateUserInput
                                {
                                    Id = o.UserId,
                                    Name = o.Name,
                                    LoginName = o.UserName,
                                    Picture = o.Picture,
                                    Phone = o.Mobile,
                                    JobNumber = o.EmployeeNo,
                                    NickName = o.NickName,
                                    Department = o.DeptName,
                                    DepartmentId = o.DeptId,
                                    JobTitle = o.JobTitle,
                                    JobState = o.State.Value,
                                    Email = o.Email,
                                    IdCardNo = o.IdCardNo,
                                    NationalityCode = o.NationalityCode,
                                    Nationality = o.Nationality,
                                    Gender = o.Gender.Value,
                                    TopQualifications = o.TopQualifications,
                                    Nation = o.Nation,
                                    NationPlace = o.NationPlace,
                                    EmployeeType = o.EmployeeTypeCode,
                                    CompanyAge = o.CompanyAge,
                                    PositionName = o.PositionName,
                                    JobLevel = o.JobLevel,
                                    StaffSystem = o.StaffSystem,
                                    StaffSystemCode = o.StaffSystemCode,
                                    BirthDate = o.BirthDate,
                                    FSUnionId = o.FSUnionId,
                                    ExtFSUnionId = o.ExtFsUnionId,
                                    Company = o.Company,
                                    CompanyNo = o.CompanyNo,
                                    Managerid = o.ManagerId
                                }).ToList();

                                Program.userService.AddOrUpdateUser(temp);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine($"{DateTime.UtcNow.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")}:Page:{page} 员工执行异常 {ex.Message}");
                            }
                        }
                        else
                        {
                            break;
                        }
                        Console.WriteLine($"{DateTime.UtcNow.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")}:Page:{page} 员工执行完成");
                    }
                    else
                    {
                        Console.WriteLine($"{DateTime.UtcNow.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")}:Page:{page} 员工获取数据失败");
                    }

                    page++;
                }
                catch (Exception ex)
                {
                    page++;
                }
            }

            page = 1;

            while (true)
            {
                try
                {
                    var info = Program.baseLotusClient.GetLotusOrgInfoList(new Lotus.Domain.Input.GetLotusOrgInfoListInput
                    {
                        PageNo = page,
                        PageSize = 100
                    });
                    if (!info.IsError)
                    {
                        if (info.Result.Data.DataList.Count > 0)
                        {
                            try
                            {
                                var temp = info.Result.Data.DataList.Select(o => new AddOrUpdateOrgInput
                                {
                                    Id = o.OrgId,
                                    OrgName = o.OrgName,
                                    EnName = o.EnName,
                                    FullName = o.FullName,
                                    ParentId = o.ParentId,
                                    Type = o.Type,
                                    State = o.State,
                                    Sapcode = o.Sapcode,
                                    CostCenter = o.CostCenter,
                                    CostCenterCode = o.CostCenterCode,
                                    WechatId = o.WechatId,
                                    FSOrgId = o.FSOrgId,
                                    FSOrgChatId = o.FSOrgChatId,
                                    OrgManger = o.OrgManger,
                                    OrgMangeraCode = o.OrgMangeraCode,
                                    EffectiveTime = o.EffectiveTime,
                                    ExpirationTime = o.ExpirationTime,
                                    Level = o.Level,
                                    Property = o.Property,
                                }).ToList();
                                Program.userService.AddOrUpdateOrg(temp);
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine($"{DateTime.UtcNow.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")}:Page:{page} 组织执行异常 {ex.Message}");
                            }
                        }
                        else
                        {
                            break;
                        }
                        Console.WriteLine($"{DateTime.UtcNow.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")}:Page:{page} 组织执行完成");
                    }
                    else
                    {
                        Console.WriteLine($"{DateTime.UtcNow.AddHours(8).ToString("yyyy-MM-dd HH:mm:ss")}:Page:{page} 组织获取数据失败");
                    }

                    page++;
                }
                catch (Exception ex)
                {
                    page++;
                }
            }

            redisLock.Unlock();

            return null;
        }
    }
    public class CreatTableJob : IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            if (DateTime.Now.AddDays(1).Year == DateTime.Now.Year + 1)
            {
                Program.fsql.Select<UserVisitRecord>().AsTable((type, oldname) => $"{oldname}_{DateTime.Now.Year + 1}").ToSql(a => a.Id);
                Program.fsql.Select<UserModuleVisitRecord>().AsTable((type, oldname) => $"{oldname}_{DateTime.Now.Year + 1}").ToSql(a => a.Id);
            }
            return null;
        }
    }
}